package sub

import (
	"fmt"
	"quipus/cmd/qpc/sub"
	"quipus/internal/utils"
	v1pb "quipus/proto/gen/api/v1"
	cpb "quipus/proto/gen/common"

	"strings"

	"github.com/spf13/cobra"
)

var (
	subjectId       int32
	topics          []string
	useGranaryTopic bool
	topicPath       string
)

func init() {
	createCmd.PersistentFlags().Int32VarP(&subjectId, "subject", "s", 0, "the subject id of subject that the topic belongs to")
	createCmd.PersistentFlags().StringSliceVarP(&topics, "topic", "t", []string{}, "the topic content list title:summary#unit1=unit1summary|unit2=unit2summary")
	createCmd.PersistentFlags().BoolVarP(&useGranaryTopic, "use_granary_topic", "g", true, "use subject attached granary topic, default true")
	createCmd.PersistentFlags().StringVarP(&topicPath, "topic-path", "p", "", "the topic file path")

	topicCmd.AddCommand(createCmd)
}

var createCmd = &cobra.Command{
	Use:   "create",
	Short: "Run the cmd to create topics",
	RunE: func(cmd *cobra.Command, args []string) error {
		qconn, e := sub.NewGrpcConnect(sub.QpConfig.QPAddress)
		if e != nil {
			return e
		}

		qclient := v1pb.NewSubjectServiceClient(qconn)
		ctxWithToken := sub.NewCtxWithToken(sub.QpConfig.Token)
		urn := utils.BuildUrn(utils.SubjectUrnPrefix, subjectId)
		var topicDefs []*cpb.TopicDef
		if len(topics) > 0 {
			topicDefs = composeTopicDef()
		} else if len(topicPath) > 0 {
			topicDefs = loadTopicDef()
		}

		in := &v1pb.CreateTopicRequest{SubjectUrn: urn, Topics: topicDefs, UseGranaryTopic: useGranaryTopic}
		fmt.Print("input msg:", in)

		rsp, err := qclient.CreateTopic(ctxWithToken, in)
		if err != nil {
			return err
		}
		fmt.Print(rsp)
		fmt.Println("ID      URN              TITLE           CONTENT")
		if rsp != nil {
			for index, v := range rsp.Topics {
				p := v.Primary
				seq := index + 1
				fmt.Printf("%5d  %10s %10s    %12s   \n", seq, p.Urn, p.Title, p.Summary)
				units := v.Units
				for j, u := range units {
					s := fmt.Sprintf("%d-%d", seq, j+1)
					fmt.Printf("%5s  %10s %10s    %12s   \n", s, u.Urn, u.Title, u.Summary)
				}
			}
		}
		return nil
	},
}

func composeTopicDef() []*cpb.TopicDef {
	var topicDefs []*cpb.TopicDef
	for _, topic := range topics {
		a := strings.Split(topic, ":")

		tdef := &cpb.TopicDef{}

		p := &cpb.TopicUnit{Title: a[0]}
		if len(a) != 2 {
			continue
		}
		content := a[1]
		units := strings.Split(content, "#")

		p.Summary = units[0]
		tdef.Primary = p
		if len(units) > 1 {
			topicUnits := strings.Split(units[1], "||")
			for _, unit := range topicUnits {
				ua := strings.Split(unit, "=")
				if len(ua) != 2 {
					continue
				}
				u := &cpb.TopicUnit{Title: ua[0], Summary: ua[1]}
				tdef.Units = append(tdef.Units, u)
			}
		}

		topicDefs = append(topicDefs, tdef)
	}
	return topicDefs
}

func loadTopicDef() []*cpb.TopicDef {
	var topicDefs []*cpb.TopicDef

	err := utils.ReadYamlConfig(topicPath, &topicDefs)
	if err != nil {
		return nil
	}
	return topicDefs
}
